import {KeyboardEvent} from "./event";
import {TextModel, SelectionModel} from './models'
import {ViewProvider, SourceView} from "./view";
import {
    InsertTextOperation,
    SetSelectionOperation,
    RemoveTextOperation,
} from "./operations";
import {ViewMode} from "./types";

export default class Editor {
    private readonly container: HTMLElement;
    private eventHandler!: KeyboardEvent;
    private textModel_!: TextModel;
    private selectionModel_!: SelectionModel;
    private view_: SourceView | undefined;
    private viewProvider_: ViewProvider;

    constructor(elementById: HTMLElement) {
        this.container = elementById
        this.viewProvider_ = new ViewProvider()

    }

    init() {
        this.textModel_ = new TextModel()
        this.selectionModel_ = new SelectionModel(this.textModel_)
        this.view_ = this.viewProvider_.provide(ViewMode.source, this.textModel_, this.selectionModel_, this.container)
        this.eventHandler = new KeyboardEvent(this, this.container, this.view_)
        this.eventHandler.addListeners()
    }

    getTextModel() {
        return this.textModel_
    }

    getSelectionModel() {
        return this.selectionModel_
    }

    apply(operation: any) {
        operation.apply(this)
    }

    inverse(operation: any) {
        operation.inverse(this)
    }

    insertTextAtCursor(text: string) {
        const selection = this.selectionModel_.getSelection()
        let startIndex = selection.anchor
        let cursorIndex;
        if (!this.selectionModel_.isCollapsed()) {
            const removeTextOperation = new RemoveTextOperation(selection.anchor, selection.focus)
            this.apply(removeTextOperation)
            if (this.selectionModel_.isBackward()) {
                startIndex = selection.focus;
            }
        }
        cursorIndex = startIndex + text.length
        const insertTextOperation = new InsertTextOperation(text, startIndex);
        this.apply(insertTextOperation)
        this.setSelection(cursorIndex, cursorIndex)
    }

    deleteTextAtCursor() {
        const selection = this.selectionModel_.getSelection()
        let startIndex = selection.anchor
        if (!this.selectionModel_.isCollapsed()) {
            this.apply(new RemoveTextOperation(selection.anchor, selection.focus));
            if (this.selectionModel_.isBackward()) {
                startIndex = selection.focus;
            }
        } else if (selection.anchor > 0) {
            this.apply(new RemoveTextOperation(selection.anchor - 1, selection.focus));
            startIndex--
        }
        this.setSelection(startIndex, startIndex)
    }

    //撤销
    undo() {
        console.log('撤销')
    }

    //回退
    redo() {
        console.log('回退')
    }

    setSelection(anchor: number, focus: number) {
        const selectionOperation = new SetSelectionOperation({anchor, focus})
        this.apply(selectionOperation)
    }

}